package neuron;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import neuron.file.AuxData;
import neuron.file.AuxData.Type;

import common.statistics.Series;
import common.statistics.XYSeries;

public class NetworkStatistics implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -4117711519252790408L;
	
	List<Network> nets;	
	
	public NetworkStatistics(Network net) {
		nets = new ArrayList<Network>();
		nets.add(net);
	}

	public NetworkStatistics(List<Network> nets) {
		this.nets = nets;
	}
	
	public Series basalTermSegCountDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().basalTermSegCountDist());
			}
		}
		return s;
	}
	
	public Series basalAsymIndexDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().basalAsymIndexDist());
			}
		}
		return s;
	}
	
	public Series obliqueTermSegCountDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().obliqueTermSegCountDist());
			}
		}
		return s;
	}
	
	public Series obliqueAsymIndexDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().obliqueAsymIndexDist());
			}
		}
		return s;
	}

	public Series tuftTermSegCountDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().tuftTermSegCountDist());
			}
		}
		return s;
	}
	
	public Series tuftAsymIndexDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().tuftAsymIndexDist());
			}
		}
		return s;
	}
/*
	public Series apicalTermSegCountDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.add(n.statistics().apicalTermSegCount());
			}
		}
		return s;
	}
	
	public Series apicalAsymIndexDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.add(n.statistics().apicalAsymIndex());
			}
		}
		return s;
	}
	*/
	public Series basalTermSegLenDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().basalTermSegLenDist());
			}
		}
		return s;
	}

	public Series basalIntSegLenDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().basalIntSegLenDist());
			}
		}
		return s;
	}

	public Series tuftTermSegLenDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().tuftTermSegLenDist());
			}
		}
		return s;
	}

	public Series tuftIntSegLenDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().tuftIntSegLenDist());
			}
		}
		return s;
	}
/*
	public Series apicalTermSegLenDist()
	{
		Series s = new Series();		
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().apicalTermSegLenDist());
			}
		}
		return s;
	}

	public Series apicalIntSegLenDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().apicalIntSegLenDist());
			}
		}
		return s;
	}
*/
	public Series obliqueTermSegLenDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().obliqueTermSegLenDist());
			}
		}
		return s;
	}

	public Series obliqueIntSegLenDist()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().obliqueIntSegLenDist());
			}
		}
		return s;
	}
	
	private List<Neuron> neurons()
	{
		List<Neuron> lst = new ArrayList<Neuron>();
		for (Network net : nets) {
			for (Neuron n : net) {
				lst.add(n);
			}
		}
		return lst;
	}
	

	private int age(Neuron n)
	{
		String filename = (String) n.getMetadata("FILE");
		if (filename == null) return -1;
		filename = filename.substring(0, filename.indexOf('.'));
		int age = AuxData.getValue(filename, AuxData.Type.AGE);
		return age;
	}
	 
	private int brainsize(Neuron n)
	{
		String filename = (String) n.getMetadata("FILE");
		if (filename == null) return -1;
		filename = filename.substring(0, filename.indexOf('.'));
		int age = AuxData.getValue(filename, AuxData.Type.PIA_WM);
		return age;
	}
	
	
	public XYSeries ageBasalNTSPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().basalTermSegCountDist().mean());
		}
		return xy;
	}
 
	
	public XYSeries ageObliqueNTSPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().obliqueTermSegCountDist().mean());
		}
		return xy;
	}
	 
	
	public XYSeries ageTuftNTSPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().tuftTermSegCountDist().mean());
		}
		return xy;
	}
	

	public XYSeries ageBasalISLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().basalIntSegLenDist().mean());
		}
		return xy;
	}
 
	
	public XYSeries ageObliqueISLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().obliqueIntSegLenDist().mean());
		}
		return xy;
	}
	 
	
	public XYSeries ageTuftISLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().tuftIntSegLenDist().mean());
		}
		return xy;
	}
	

	public XYSeries ageBasalTSLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().basalTermSegLenDist().mean());
		}
		return xy;
	}
 
	
	public XYSeries ageObliqueTSLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().obliqueTermSegLenDist().mean());
		}
		return xy;
	}
	 
	
	public XYSeries ageTuftTSLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(age(n), n.statistics().tuftTermSegLenDist().mean());
		}
		return xy;
	}
	

	public XYSeries brainsizeBasalNTSPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().basalTermSegCountDist().mean());
		}
		return xy;
	}
 
	
	public XYSeries brainsizeObliqueNTSPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().obliqueTermSegCountDist().mean());
		}
		return xy;
	}
	 
	
	public XYSeries brainsizeTuftNTSPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().tuftTermSegCountDist().mean());
		}
		return xy;
	}
	

	public XYSeries brainsizeBasalISLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().basalIntSegLenDist().mean());
		}
		return xy;
	}
 
	
	public XYSeries brainsizeObliqueISLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().obliqueIntSegLenDist().mean());
		}
		return xy;
	}
	 
	
	public XYSeries brainsizeTuftISLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().tuftIntSegLenDist().mean());
		}
		return xy;
	}
	

	public XYSeries brainsizeBasalTSLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().basalTermSegLenDist().mean());
		}
		return xy;
	}
 
	
	public XYSeries brainsizeObliqueTSLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().obliqueTermSegLenDist().mean());
		}
		return xy;
	}
	 
	
	public XYSeries brainsizeTuftTSLenPerNeuron()
	{
		XYSeries xy = new XYSeries();	
		for (Neuron n : neurons()) {
			xy.add(brainsize(n), n.statistics().tuftTermSegLenDist().mean());
		}
		return xy;
	}


	public Series basalBranchingAngles()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().basalBranchAngles());
			}
		}
		return s;

	}

	public Series obliqueBranchingAngles()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().obliqueBranchAngles());
			}
		}
		return s;

	}

	public Series tuftBranchingAngles()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().tuftBranchAngles());
			}
		}
		return s;
	}

	public Series basalTurningAngles()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().basalTurningAngles());
			}
		}
		return s;

	}

	public Series obliqueTurningAngles()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().obliqueTurningAngles());
			}
		}
		return s;

	}

	public Series tuftTurningAngles()
	{
		Series s = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				s.merge(n.statistics().tuftTurningAngles());
			}
		}
		return s;
	}

	public Series[] basalSholl()
	{
		double maxR = 200, delta = 10;
		Series[] s = new Series[(int) (maxR / delta)];
		for (int i = 0; i < s.length; i++) s[i] = new Series();
		for (Network net : nets) {
			for (Neuron n : net) {
				int [] sholl = n.statistics().basalSholl(delta);
				for (int i = 0; i < s.length; i++) s[i].add(sholl[i]);
			}
		}
		return s;
	}
}
